using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

using SypConst.Garbage;
using SypConst.Path;
using SypEngine.SiteConfig;

namespace SypEngine
{
    public class SypCommandHandler : SypSuspendableThread
    {
        protected Queue CommandQueue = null;
        protected SypSiteHandler SypSites = null;

        public void Enqueue(String[] parameters)
        {
            lock (CommandQueue.SyncRoot)
            {
                CommandQueue.Enqueue(parameters);
            }
            Resume();
        }

        private string[] Dequeue()
        {
            lock (CommandQueue.SyncRoot)
            {
                return (string[])CommandQueue.Dequeue();
            }
        }

        private bool isEmpty() {
            lock (CommandQueue.SyncRoot)
            {
                return (CommandQueue.Count == 0) ? true : false;
            }
        }

        public SypCommandHandler(SetText WriteMethod, VisitorCallBack[] Callbacks, SypSiteHandler SypSites)
            : base(WriteMethod)
        {
            CommandQueue = new Queue();
            this.SypSites = SypSites;
            
            List<SypVisitor> VisitorList = SypSites.GetVisitors();
            if (VisitorList != null){
                foreach(SypVisitor sv in VisitorList){
                    this.evt_onTerminatedRequest += new onTerminatedRequest(sv.OnTerminatedRequest);
                }
            }
        }

        protected virtual void PreProcess() {
            this.LoadActions();
        }
        protected virtual void PostProcess() {
            this.SaveActions();
        }

        protected virtual void LoadActions() { }
        protected virtual void SaveActions() { }

        protected override void OnDoWork()
        {
            try
            {
                PreProcess();
                while (false == HasTerminateRequest())
                {
                    Boolean awokenByTerminate = SuspendIfNeeded();
                    if (awokenByTerminate)
                    {
                        return;
                    }

                    if (SypSites != null)
                    {
                        while (!this.isEmpty() && !HasTerminateRequest())
                        {
                            string[] commandLine = Dequeue();
                            if (commandLine != null && commandLine.Length > 0)
                            {
                                string command = commandLine[0];
                                SypSites.Accept(command, commandLine);
                            }
                            else
                                OutputMethod("Command line syntax is incorrect.", Output.ERROR);
                        }
                        Suspend();
                    }
                    else
                        OutputMethod("No site conf found.", Output.OUT);

                }
            }
            finally
            {
                PostProcess();
            }
        }

    }
}
